Micron Document
πŸŽ–οΈGitΠ―Ρ€Π°πŸŽ–οΈ

Node / meshtastic / Meshtastic-Android / files / core / service / src / commonMain / kotlin / org / meshtastic / core / service / AdminControllerImpl.kt

Displaying Raw β€’ Download

core/service/src/commonMain/kotlin/org/meshtastic/core/service/AdminControllerImpl.kt 1230c36cdbe2ac71a9b64e8a70414f9b7eaf842e (1230c36c) Text, 11.80 KB

T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.core.service

Tff7b72import T7ee787co.touchlab.kermit.Logger
Tff7b72import T7ee787kotlinx.coroutines.CoroutineScope
Tff7b72import T7ee787kotlinx.coroutines.flow.firstOrNull
Tff7b72import T7ee787okio.ByteString
Tff7b72import T7ee787okio.ByteString.Companion.toByteString
Tff7b72import T7ee787org.meshtastic.core.common.util.handledLaunch
Tff7b72import T7ee787org.meshtastic.core.model.Position
Tff7b72import T7ee787org.meshtastic.core.repository.AdminController
Tff7b72import T7ee787org.meshtastic.core.repository.AdminEditScope
Tff7b72import T7ee787org.meshtastic.core.repository.CommandSender
Tff7b72import T7ee787org.meshtastic.core.repository.NodeManager
Tff7b72import T7ee787org.meshtastic.core.repository.RadioConfigRepository
Tff7b72import T7ee787org.meshtastic.proto.AdminMessage
Tff7b72import T7ee787org.meshtastic.proto.Channel
Tff7b72import T7ee787org.meshtastic.proto.Config
Tff7b72import T7ee787org.meshtastic.proto.HamParameters
Tff7b72import T7ee787org.meshtastic.proto.ModuleConfig
Tff7b72import T7ee787org.meshtastic.proto.OTAMode
Tff7b72import T7ee787org.meshtastic.proto.User

T8b949e/**
* [AdminController] implementation: local/remote configuration, channels, owner, device lifecycle, and the
* [editSettings] transaction.
*
* Focused collaborator of [RadioControllerImpl]. Builds [AdminMessage] protos directly and delegates to [CommandSender]
* for transport, mirroring the SDK's `AdminApiImpl` pattern. Config/channel writes use fire-and-forget optimistic local
* persistence ([handledLaunch]): the device is the source of truth and re-sends its full config on every connection, so
* persistence is a cache optimization, not a correctness requirement.
*/
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffTooManyFunctionsTa5d6ff"Tb4b4b4)
Tff7b72internal Tff7b72class T56d364AdminControllerImplTb4b4b4(
Tff7b72private Tff7b72val Te6edf3commandSenderTb4b4b4: Te6edf3CommandSenderTb4b4b4,
Tff7b72private Tff7b72val Te6edf3nodeManagerTb4b4b4: Te6edf3NodeManagerTb4b4b4,
Tff7b72private Tff7b72val Te6edf3radioConfigRepositoryTb4b4b4: Te6edf3RadioConfigRepositoryTb4b4b4,
Tff7b72private Tff7b72val Te6edf3scopeTb4b4b4: Te6edf3CoroutineScopeTb4b4b4,
Tb4b4b4) Tb4b4b4: Te6edf3AdminController Tb4b4b4{

Tff7b72private Tff7b72val Te6edf3myNodeNumTb4b4b4: Tffa657Int
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3nodeManagerTb4b4b4.Te6edf3myNodeNumTb4b4b4.Te6edf3value Tff7b72?: T79c0ff0

T8b949e// ── Owner ───────────────────────────────────────────────────────────────

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsetOwnerTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3userTb4b4b4: Te6edf3UserTb4b4b4, Te6edf3packetIdTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3packetIdTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3set_owner Tff7b72= Te6edf3userTb4b4b4) Tb4b4b4}
Te6edf3nodeManagerTb4b4b4.Te6edf3handleReceivedUserTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3userTb4b4b4)
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffgetOwnerTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3packetIdTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3packetIdTb4b4b4, Te6edf3wantResponse Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3get_owner_request Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsetHamModeTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3hamParametersTb4b4b4: Te6edf3HamParametersTb4b4b4, Te6edf3packetIdTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destNum Tff7b72!Tff7b72= Te6edf3nodeManagerTb4b4b4.Te6edf3myNodeNumTb4b4b4.Te6edf3valueTb4b4b4) Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3w Tb4b4b4{ Ta5d6ff"Ta5d6ffIgnoring setHamMode for node Tffd700$Te6edf3destNumTa5d6ff β€” ham onboarding targets the local node onlyTa5d6ff" Tb4b4b4}
Tff7b72return
Tb4b4b4}
T8b949e// Firmware applies tx_power/frequency to the LoRa config verbatim, so echo the node's current
T8b949e// values to keep a re-send (e.g. a callsign edit while already licensed) from wiping overrides.
Tff7b72val Te6edf3lora Tff7b72= Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3localConfigFlowTb4b4b4.Te6edf3firstOrNullTb4b4b4(Tb4b4b4)Tff7b72?.Te6edf3lora Tff7b72?: Te6edf3ConfigTb4b4b4.Te6edf3LoRaConfigTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3params Tff7b72= Te6edf3hamParametersTb4b4b4.Te6edf3copyTb4b4b4(Te6edf3tx_power Tff7b72= Te6edf3loraTb4b4b4.Te6edf3tx_powerTb4b4b4, Te6edf3frequency Tff7b72= Te6edf3loraTb4b4b4.Te6edf3override_frequencyTb4b4b4)
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3packetIdTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3set_ham_mode Tff7b72= Te6edf3paramsTb4b4b4) Tb4b4b4}
Tff7b72val Te6edf3currentUser Tff7b72= Te6edf3nodeManagerTb4b4b4.Te6edf3nodeDBbyNodeNumTff7b72[Te6edf3destNumTff7b72]Tff7b72?.Te6edf3user Tff7b72?: Te6edf3UserTb4b4b4(Tb4b4b4)
Te6edf3nodeManagerTb4b4b4.Te6edf3handleReceivedUserTb4b4b4(
Te6edf3destNumTb4b4b4,
Te6edf3currentUserTb4b4b4.Te6edf3copyTb4b4b4(
Te6edf3long_name Tff7b72= Te6edf3hamParametersTb4b4b4.Te6edf3call_signTb4b4b4,
Te6edf3short_name Tff7b72= Te6edf3hamParametersTb4b4b4.Te6edf3short_nameTb4b4b4,
Te6edf3is_licensed Tff7b72= Tff7b72trueTb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}

T8b949e// ── Configuration ─────────────────────────────────────────────────────────

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsetLocalConfigTb4b4b4(Te6edf3configTb4b4b4: Te6edf3ConfigTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3myNodeNumTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3set_config Tff7b72= Te6edf3configTb4b4b4) Tb4b4b4}
Te6edf3scopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3setLocalConfigTb4b4b4(Te6edf3configTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsetConfigTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3configTb4b4b4: Te6edf3ConfigTb4b4b4, Te6edf3packetIdTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3packetIdTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3set_config Tff7b72= Te6edf3configTb4b4b4) Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3destNum Tff7b72=Tff7b72= Te6edf3nodeManagerTb4b4b4.Te6edf3myNodeNumTb4b4b4.Te6edf3valueTb4b4b4) Tb4b4b4{
Te6edf3scopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3setLocalConfigTb4b4b4(Te6edf3configTb4b4b4) Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffgetConfigTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3configTypeTb4b4b4: Tffa657IntTb4b4b4, Te6edf3packetIdTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3packetIdTb4b4b4, Te6edf3wantResponse Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3configType Tff7b72=Tff7b72= Te6edf3AdminMessageTb4b4b4.Te6edf3ConfigTypeTb4b4b4.Te6edf3SESSIONKEY_CONFIGTb4b4b4.Te6edf3valueTb4b4b4) Tb4b4b4{
Te6edf3AdminMessageTb4b4b4(Te6edf3get_device_metadata_request Tff7b72= Tff7b72trueTb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3AdminMessageTb4b4b4(Te6edf3get_config_request Tff7b72= Te6edf3AdminMessageTb4b4b4.Te6edf3ConfigTypeTb4b4b4.Te6edf3fromValueTb4b4b4(Te6edf3configTypeTb4b4b4)Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsetModuleConfigTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3configTb4b4b4: Te6edf3ModuleConfigTb4b4b4, Te6edf3packetIdTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3packetIdTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3set_module_config Tff7b72= Te6edf3configTb4b4b4) Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3destNum Tff7b72=Tff7b72= Te6edf3nodeManagerTb4b4b4.Te6edf3myNodeNumTb4b4b4.Te6edf3valueTb4b4b4) Tb4b4b4{
Te6edf3configTb4b4b4.Te6edf3statusmessageTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3sm Tff7b72-Tff7b72> Te6edf3nodeManagerTb4b4b4.Te6edf3updateNodeStatusTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3smTb4b4b4.Te6edf3node_statusTb4b4b4) Tb4b4b4}
Te6edf3scopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3setLocalModuleConfigTb4b4b4(Te6edf3configTb4b4b4) Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffgetModuleConfigTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3moduleConfigTypeTb4b4b4: Tffa657IntTb4b4b4, Te6edf3packetIdTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3packetIdTb4b4b4, Te6edf3wantResponse Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{
Te6edf3AdminMessageTb4b4b4(Te6edf3get_module_config_request Tff7b72= Te6edf3AdminMessageTb4b4b4.Te6edf3ModuleConfigTypeTb4b4b4.Te6edf3fromValueTb4b4b4(Te6edf3moduleConfigTypeTb4b4b4)Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

T8b949e// ── Channels ────────────────────────────────────────────────────────────

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsetLocalChannelTb4b4b4(Te6edf3channelTb4b4b4: Te6edf3ChannelTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3myNodeNumTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3set_channel Tff7b72= Te6edf3channelTb4b4b4) Tb4b4b4}
Te6edf3scopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3updateChannelSettingsTb4b4b4(Te6edf3channelTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsetRemoteChannelTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3channelTb4b4b4: Te6edf3ChannelTb4b4b4, Te6edf3packetIdTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3packetIdTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3set_channel Tff7b72= Te6edf3channelTb4b4b4) Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3destNum Tff7b72=Tff7b72= Te6edf3nodeManagerTb4b4b4.Te6edf3myNodeNumTb4b4b4.Te6edf3valueTb4b4b4) Tb4b4b4{
Te6edf3scopeTb4b4b4.Te6edf3handledLaunch Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3updateChannelSettingsTb4b4b4(Te6edf3channelTb4b4b4) Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffgetChannelTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3indexTb4b4b4: Tffa657IntTb4b4b4, Te6edf3packetIdTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3packetIdTb4b4b4, Te6edf3wantResponse Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{
Te6edf3AdminMessageTb4b4b4(Te6edf3get_channel_request Tff7b72= Te6edf3index Tff7b72+ T79c0ff1Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

T8b949e// ── Ringtone & Canned Messages ─────────────────────────────────────────

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsetRingtoneTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3ringtoneTb4b4b4: Tffa657StringTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3set_ringtone_message Tff7b72= Te6edf3ringtoneTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffgetRingtoneTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3packetIdTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3packetIdTb4b4b4, Te6edf3wantResponse Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3get_ringtone_request Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsetCannedMessagesTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3messagesTb4b4b4: Tffa657StringTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3set_canned_message_module_messages Tff7b72= Te6edf3messagesTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffgetCannedMessagesTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3packetIdTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3packetIdTb4b4b4, Te6edf3wantResponse Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{
Te6edf3AdminMessageTb4b4b4(Te6edf3get_canned_message_module_messages_request Tff7b72= Tff7b72trueTb4b4b4)
Tb4b4b4}
Tb4b4b4}

T8b949e// ── Position ────────────────────────────────────────────────────────────

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsetFixedPositionTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3positionTb4b4b4: Te6edf3PositionTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3setFixedPositionTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3positionTb4b4b4)
Tb4b4b4}

T8b949e// ── Device Status & Lifecycle ───────────────────────────────────────────

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffgetDeviceConnectionStatusTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3packetIdTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3packetIdTb4b4b4, Te6edf3wantResponse Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{
Te6edf3AdminMessageTb4b4b4(Te6edf3get_device_connection_status_request Tff7b72= Tff7b72trueTb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffrebootTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3packetIdTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3i Tb4b4b4{ Ta5d6ff"Ta5d6ffReboot requested for node Tffd700$Te6edf3destNumTa5d6ff" Tb4b4b4}
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3packetIdTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3reboot_seconds Tff7b72= Te6edf3DEFAULT_DELAY_SECONDSTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffrebootToDfuTb4b4b4(Te6edf3nodeNumTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3nodeNumTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3enter_dfu_mode_request Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffrequestRebootOtaTb4b4b4(Te6edf3requestIdTb4b4b4: Tffa657IntTb4b4b4, Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3modeTb4b4b4: Tffa657IntTb4b4b4, Te6edf3hashTb4b4b4: Te6edf3ByteArray?Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3otaMode Tff7b72= Te6edf3OTAModeTb4b4b4.Te6edf3fromValueTb4b4b4(Te6edf3modeTb4b4b4) Tff7b72?: Te6edf3OTAModeTb4b4b4.Te6edf3NO_REBOOT_OTA
Tff7b72val Te6edf3otaEvent Tff7b72=
Te6edf3AdminMessageTb4b4b4.Te6edf3OTAEventTb4b4b4(Te6edf3reboot_ota_mode Tff7b72= Te6edf3otaModeTb4b4b4, Te6edf3ota_hash Tff7b72= Te6edf3hashTff7b72?.Te6edf3toByteStringTb4b4b4(Tb4b4b4) Tff7b72?: Te6edf3ByteStringTb4b4b4.Te6edf3EMPTYTb4b4b4)
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3requestIdTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3ota_request Tff7b72= Te6edf3otaEventTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffshutdownTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3packetIdTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3packetIdTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3shutdown_seconds Tff7b72= Te6edf3DEFAULT_DELAY_SECONDSTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8fffactoryResetTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3packetIdTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3i Tb4b4b4{ Ta5d6ff"Ta5d6ffFactory reset requested for node Tffd700$Te6edf3destNumTa5d6ff" Tb4b4b4}
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3packetIdTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3factory_reset_device Tff7b72= T79c0ff1Tb4b4b4) Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffnodedbResetTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3packetIdTb4b4b4: Tffa657IntTb4b4b4, Te6edf3preserveFavoritesTb4b4b4: Tffa657BooleanTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3packetIdTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3nodedb_reset Tff7b72= Te6edf3preserveFavoritesTb4b4b4) Tb4b4b4}
Tb4b4b4}

T8b949e// ── Edit Settings (transactional) ───────────────────────────────────────

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffeditSettingsTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4, Te6edf3blockTb4b4b4: Te6edf3suspend Te6edf3AdminEditScopeTb4b4b4.Tb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTb4b4b4) Tb4b4b4{
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3begin_edit_settings Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4}
Te6edf3EditSettingsSessionTb4b4b4(Te6edf3destNumTb4b4b4)Tb4b4b4.Te6edf3blockTb4b4b4(Tb4b4b4)
Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNumTb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Te6edf3commit_edit_settings Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4}
Tb4b4b4}

T8b949e/** Binds the [AdminEditScope] operations to a fixed destination, delegating to this controller's set* methods. */
Tff7b72private Tff7b72inner Tff7b72class T56d364EditSettingsSessionTb4b4b4(Tff7b72private Tff7b72val Te6edf3destNumTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4: Te6edf3AdminEditScope Tb4b4b4{
Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsetOwnerTb4b4b4(Te6edf3userTb4b4b4: Te6edf3UserTb4b4b4) Tff7b72= Te6edf3setOwnerTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3userTb4b4b4, Te6edf3commandSenderTb4b4b4.Te6edf3generatePacketIdTb4b4b4(Tb4b4b4)Tb4b4b4)

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsetConfigTb4b4b4(Te6edf3configTb4b4b4: Te6edf3ConfigTb4b4b4) Tff7b72= Te6edf3setConfigTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3configTb4b4b4, Te6edf3commandSenderTb4b4b4.Te6edf3generatePacketIdTb4b4b4(Tb4b4b4)Tb4b4b4)

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsetModuleConfigTb4b4b4(Te6edf3configTb4b4b4: Te6edf3ModuleConfigTb4b4b4) Tff7b72=
Te6edf3setModuleConfigTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3configTb4b4b4, Te6edf3commandSenderTb4b4b4.Te6edf3generatePacketIdTb4b4b4(Tb4b4b4)Tb4b4b4)

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsetChannelTb4b4b4(Te6edf3channelTb4b4b4: Te6edf3ChannelTb4b4b4) Tff7b72=
Te6edf3setRemoteChannelTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3channelTb4b4b4, Te6edf3commandSenderTb4b4b4.Te6edf3generatePacketIdTb4b4b4(Tb4b4b4)Tb4b4b4)

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsetFixedPositionTb4b4b4(Te6edf3positionTb4b4b4: Te6edf3PositionTb4b4b4) Tff7b72=
Tff7b72thisTf0883e@AdminControllerImpl.setFixedPositionTb4b4b4(Te6edf3destNumTb4b4b4, Te6edf3positionTb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72companion Tff7b72object Tb4b4b4{
Tff7b72private Tff7b72const Tff7b72val Te6edf3DEFAULT_DELAY_SECONDS Tff7b72= T79c0ff5
Tb4b4b4}
Tb4b4b4}

Served by rngit 1.5.0 - Generated in 0.08s